#include "CalcFuncsLibrary.h"
#include <qbcalculator/include/SSSingleCalendar.h>
#include <qbcalculator/Calculator.h>

namespace{
	void int2String(unsigned int input, std::string& str){
		char buf[256] = { 0 };
		buf[0] = '\0';
		FMTBUF(buf, "%d", input);
		str = buf;
	}
}

static void getInterestRates(std::vector<ssCalculator::SSSingleInterestRate>& all_rates)
{
	int nsize = CBondMacroIndex::instance().GetSize();
	if (nsize <= 0)
		return;
	nsize = nsize + 128;
	all_rates.clear();
	all_rates.reserve(nsize);
	int ncount = CBondMacroIndex::instance().GetAllData(all_rates, nsize);
}

void calendarConvert(CBondHoliday& info, std::vector<ssCalculator::SSSingleCalendar>& all_calendars)
{
	try{
		int ntotal = 0, nsum = 0;
		for (std::map<int, BondHolidayList>::const_iterator it = info.date.begin(); it != info.date.end(); it++) {
			ntotal += it->second.holidays.size();
		}
		all_calendars.reserve(ntotal);
		std::map<int, BondHolidayList>::iterator it;
		for (it = info.date.begin(); it != info.date.end(); it++) {
			std::vector<BondHoliday>::iterator it2;
			for (it2 = it->second.holidays.begin(); it2 != it->second.holidays.end(); it2++) {
				ssCalculator::SSSingleCalendar data;
				data.country_ = it2->country;
				data.market_ = it2->market;
				int2String(it->first, data.date_);
				if (strcmp(it2->status, "T") == 0 || strcmp(it2->status, "t") == 0)//H--为节假日
					data.isBusinessDay_ = true;
				else
					data.isBusinessDay_ = false;

				all_calendars.emplace_back(data);
				nsum++;
			}
		}
	} catch (...) {
		log_error("CSSCalculator::CalendarConvert(); has a exception");
	}
}

void initCalculator()
{
	std::vector<ssCalculator::SSSingleCalendar> all_calendars;
	calendarConvert(CBondCalendar::instance().GetBondHoliday(),all_calendars);
	std::vector<ssCalculator::SSSingleInterestRate> all_rates;
	getInterestRates(all_rates);

	try{
		CSSCalculator::setCalendar(all_calendars);
		CSSCalculator::setInterestRate(all_rates);
	}catch (...){}
}

void macroIndexConvert(CBondMacroData& info, std::vector<ssCalculator::SSSingleInterestRate>& all_rates)
{
	try{
		for (CBondMacroData::CodeMacroListMap::iterator iter = info.m_values.begin(); iter != info.m_values.end(); ++iter){
			CBondMacroData::MacroValueList& vec = iter->second;
			for (CBondMacroData::MacroValueList::iterator it = vec.begin(); it != vec.end(); ++it){
				ssCalculator::SSSingleInterestRate data;
				data.index_id_ = iter->first;
				int2String(it->begin_date, data.startDate_);
				int2String(it->end_date, data.endDate_);
				data.value_ = it->fvalue / 100;
				if (data.value_ == 999999999999999.0) continue;
				all_rates.push_back(data);
			}
		}
	} catch (...){
		log_error("CSSCalculator::MacroIndexConvert(); has a exception");
	}
}

void bondFundamentalInfoConvert(xBondFundamentalInfoList_c& info, std::vector<ssCalculator::SSSingleRawBondFundamentalInfo>& all_info)
{
	try{
		all_info.reserve(info.m_List.size());
		std::list<xBondFundamentalInfo_c>::iterator it;
		for (it = info.m_List.begin(); it != info.m_List.end(); it++){
			ssCalculator::SSSingleRawBondFundamentalInfo data;
			data.Bond_Key_ = it->m_Bond_Key;
			data.Bond_ID_ = it->m_Bond_ID;
			data.Interest_Start_Date_ = it->m_Interest_Start_Date;
			data.Maturity_Date_ = it->m_Maturity_Date;
			data.First_Coupon_Date_ = it->m_First_Coupon_Date;
			data.Option_Type_ = it->m_Option_Type;
			data.Option_Style_ = it->m_Option_Style;
			data.Call_No_ = it->m_Call_No;
			data.Call_Str_ = it->m_Call_Str;
			data.Put_No_ = it->m_Put_No;
			data.Put_Str_ = it->m_Put_Str;
			data.First_Exchg_Bond_Key_ = it->m_First_Exchg_Bond_Key;
			data.First_Exchg_No_ = it->m_First_Exchg_No;
			data.First_Exchg_Str_ = it->m_First_Exchg_Str;
			data.Sec_Exchg_No_ = it->m_Sec_Exchg_No;
			data.Sec_Exchg_Year_ = it->m_Sec_Exchg_Year;
			data.Assign_Trans_Key_ = it->m_Assign_Trans_Key;
			data.Assign_Trans_No_ = it->m_Assign_Trans_No;
			data.Assign_Trans_Str_ = it->m_Assign_Trans_Str;
			data.Compensate_Rate_ = it->m_Compensate_Rate;
			data.Compensate_From_ = it->m_Compensate_From;
			data.Option_Exercise_ = it->m_Option_Exercise;
			data.Option_Exercise_Date_ = it->m_Option_Exercise_Date;
			data.Coupon_Type_ = it->m_Coupon_Type;
			data.Coupon_Rate_Spread_ = it->m_Coupon_Rate_Spread;
			data.Coupon_Frequency_ = it->m_Coupon_Frequency;
			data.Compound_Frequency_ = it->m_Compound_Frequency;
			data.Interest_Basis_ = it->m_Interest_Basis;
			data.Coupon_Dist_ = it->m_Coupon_Dist;
			data.FRN_Multiplier_ = it->m_FRN_Multiplier;
			data.FRN_Index_ID_ = it->m_FRN_Index_ID;
			data.First_Index_Rate_ = it->m_First_Index_Rate;
			data.Fixing_Frequency_ = it->m_Fixing_Frequency;
			data.Fixing_MA_Days_ = it->m_Fixing_MA_Days;
			data.Fixing_Preceds_ = it->m_Fixing_Preceds;
			data.Fixing_Calendar_Key_ = it->m_Fixing_Calendar_Key;
			data.Fixing_Tailing_ = it->m_Fixing_Tailing;
			data.Fixing_Digit_ = it->m_Fixing_Digit;
			data.Reset_Effective_ = it->m_Reset_Effective;
			data.Cap_ = it->m_Cap;
			data.Flr_ = it->m_Flr;
			data.Simple_Compound_ = it->m_Simple_Compound;
			data.Variable_Schedule_ = it->m_Variable_Schedule;
			data.Coupon_Day_Adjust_ = it->m_Coupon_Day_Adjust;
			data.Coupon_Day_DMC_ = it->m_Coupon_Day_DMC;
			data.Coupon_Calendar_Key_ = it->m_Coupon_Calendar_Key;
			data.Pricing_Conv_ = it->m_Pricing_Conv;
			data.Issue_Price_ = it->m_Issue_Price;
			data.Redemption_No_ = it->m_Redemption_No;
			data.Redemption_Str_ = it->m_Redemption_Str;
			data.Maturity_Adjust_ = it->m_Maturity_Adjust;
			data.Maturity_DMC_ = it->m_Maturity_DMC;
			data.Maturity_Calendar_Key_ = it->m_Maturity_Calendar_Key;
			data.Listed_Date_ = it->m_Listed_Date;
			all_info.emplace_back(data);
		}
	}catch (...){
		log_error("CSSCalculator::BondFundamentalInfoConvert(); has a exception");
	}
}
